home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / ant.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  11.7 KB  |  472 lines

  1. #include "ant.hpp"
  2. #include "lisp.hpp"
  3. #include "lisp_gc.hpp"
  4. #include "compiled.hpp"
  5. #include "objects.hpp"
  6. #include "level.hpp"
  7. #include "game.hpp"
  8. #include "jrand.hpp"
  9. #include "clisp.hpp"
  10. #include "dev.hpp"
  11. #include <ctype.h>
  12.  
  13. enum {  ANT_need_to_dodge,     // ant vars
  14.     ANT_no_see_time,
  15.     ANT_hide_flag };
  16.  
  17. void *ant_ai();
  18.  
  19. int can_see(game_object *o, long x1, long y1, long x2, long y2)
  20. {
  21.   long nx2=x2,ny2=y2;
  22.   current_level->foreground_intersect(x1,y1,x2,y2);
  23.   if (x2!=nx2 || y2!=ny2) return 0;
  24.  
  25.   current_level->boundary_setback(o,x1,y1,x2,y2);
  26.   return (x2==nx2 && y2==ny2);
  27. }
  28.  
  29.  
  30. // if we first saw the player or it's been a while since we've seen the player then do a scream
  31. static void scream_check(game_object *o, game_object *b)
  32. {
  33.   if (can_see(o,o->x,o->y,b->x,b->y))
  34.   {
  35.     if (o->lvars[ANT_no_see_time]==0 || o->lvars[ANT_no_see_time]>20)
  36.       the_game->play_sound(S_ASCREAM_SND,127,o->x,o->y);      
  37.     o->lvars[ANT_no_see_time]=1;
  38.   } else o->lvars[ANT_no_see_time]++;
  39. }
  40.  
  41. int ant_congestion(game_object *o)
  42. {
  43.   for (game_object *d=current_level->first_active_object();d;d=d->next_active)
  44.   {
  45.     if (d->otype==o->otype && abs(o->x-d->x)<30 && abs(o->x-d->y)<20) return 1;
  46.   }
  47.   return 0;
  48. }
  49.  
  50. int ant_dodge(game_object *o)
  51. {
  52.   if (o->lvars[ANT_need_to_dodge]==1)
  53.   {
  54.     o->lvars[ANT_need_to_dodge]=0;
  55.     if ((jrand()%2)==0)
  56.     {
  57.       o->set_state(stopped);
  58.       o->set_aistate(ANT_JUMP);
  59.       if (!can_see(o,o->x,o->y,o->x,o->y-120))   // is there a roof above?
  60.       {
  61.     o->set_yvel(-17);
  62.     o->set_xvel(0);
  63.     o->set_aistate(ANT_JUMP_ROOF);
  64.     ant_ai();
  65.       } else
  66.       {
  67.     o->set_yvel(-12);
  68.     if (o->direction>0)
  69.       o->set_xvel(22);
  70.     else o->set_xvel(-22);
  71.     o->set_aistate(ANT_JUMP);
  72.       }
  73.     }
  74.     return 1;
  75.   } else return 0;
  76. }
  77.  
  78. static int alien_wait_time()
  79. {
  80.   void *v=symbol_value(l_difficulty);
  81.   if (v==l_easy)
  82.     return 6;
  83.   else if (v==l_medium)
  84.    return 4;
  85.   else if (v==l_hard)
  86.     return 2;
  87.   else return 1;
  88. }
  89.  
  90. static int can_hit_player(game_object *o, game_object *b)
  91. {  
  92.   return can_see(o,o->x+(o->direction>0?15:-15),o->y-15,b->x,b->y-15);
  93. }
  94.  
  95. static void fire_at_player(game_object *o, game_object *b)
  96. {
  97.   long firex=o->x+(o->direction>0?15:-15),firey=o->y-15,
  98.        playerx=b->x+b->xvel()*8,playery=b->y-15+b->yvel()*2;
  99.   if (can_see(o,o->x,o->y,firex,firey) && can_see(o,firex,firey,playerx,playery))
  100.   {
  101.     int angle=lisp_atan2(firey-playery,playerx-firex);
  102.     void *call_list=NULL;
  103.     p_ref r1(call_list);
  104.     push_onto_list(new_lisp_pointer(b),call_list);
  105.     push_onto_list(new_lisp_number(angle),call_list);
  106.     push_onto_list(new_lisp_number(firey),call_list);
  107.     push_onto_list(new_lisp_number(firex),call_list);
  108.     push_onto_list(new_lisp_number(o->aitype()),call_list);
  109.     push_onto_list(new_lisp_pointer(o),call_list);
  110.     eval_user_fun((lisp_symbol *)l_fire_object,call_list);
  111.     o->set_state((character_state)S_weapon_fire);
  112.   }
  113. }
  114.  
  115. void *ant_ai()
  116. {
  117.   game_object *o=current_object,*b;
  118.  
  119.   if (o->hp()==0)    // if we are dead return NULL and get deleted
  120.   {
  121.     if (o->state==dead)
  122.       return NULL;
  123.     else o->set_state(dead);
  124.     return true_symbol;
  125.   }
  126.  
  127.  
  128.   if (o->state==flinch_up || o->state==flinch_down)
  129.   {
  130.     o->next_picture();
  131.     return true_symbol;
  132.   }
  133.  
  134.  
  135.   switch (o->aistate())
  136.   {
  137.     case ANT_START :
  138.     {
  139.       o->set_state((character_state)S_hanging);
  140.       if (o->lvars[ANT_hide_flag])
  141.         o->set_aistate(ANT_HIDING);
  142.  
  143.       else o->set_aistate(ANT_HANGING);
  144.     } break;
  145.     case ANT_HIDING :
  146.     {
  147.       if ((jrand()%128)==0) the_game->play_sound(S_SCARE_SND,127,o->x,o->y);
  148.       if (o->otype!=S_HIDDEN_ANT)
  149.       {
  150.     o->change_type(S_HIDDEN_ANT);      // switch types so noone hurts us.
  151.     o->set_state(stopped);
  152.     o->set_aistate(ANT_HIDING);
  153.       }
  154.  
  155.       int fall=0;
  156.       if (o->total_objects()==0)
  157.       {
  158.     if (player_list->next)
  159.       b=current_level->attacker(current_object);
  160.     else b=player_list->focus;
  161.     if (abs(b->x-o->x)<130 && (o->y<b->y))
  162.       fall=1;
  163.       }      
  164.       else if (o->get_object(0)->aistate()!=0)
  165.         fall=1;
  166.       
  167.       if (fall)
  168.       {
  169.     o->change_type(S_ANT_ROOF);
  170.     o->set_state((character_state)S_falling);
  171.     o->set_aistate(ANT_FALL_DOWN);
  172.     o->set_targetable(1);
  173.       } else o->set_targetable(0);
  174.     } break;
  175.     case ANT_HANGING :
  176.     {
  177.       int fall=0;
  178.       if ((jrand()%128)==0) the_game->play_sound(S_SCARE_SND,127,o->x,o->y);
  179.       if (o->lvars[ANT_hide_flag])
  180.         o->set_aistate(ANT_HIDING);
  181.       else
  182.       {
  183.     o->set_state((character_state)S_hanging);
  184.     if (o->total_objects())
  185.     {
  186.       if (o->get_object(0)->aistate()!=0)
  187.       fall=1;
  188.     } else
  189.     {
  190.       if (player_list->next)
  191.         b=current_level->attacker(current_object);
  192.       else b=player_list->focus;
  193.       if (abs(b->x-o->x)<130 && (o->y<b->y))
  194.       fall=1;
  195.     }
  196.     if (fall)
  197.     {
  198.       o->set_state((character_state)S_fall_start);
  199.       o->set_aistate(ANT_FALL_DOWN);
  200.       o->set_targetable(1);
  201.     } else o->set_targetable(0);
  202.       }
  203.       
  204.     } break;
  205.     case ANT_FALL_DOWN :
  206.     {
  207.       o->set_state((character_state)S_falling);
  208.        
  209.       if (player_list->next)
  210.       b=current_level->attacker(current_object);
  211.       else b=player_list->focus;
  212.       
  213.       scream_check(o,b);
  214.       int ret=o->mover(0,0,0);
  215.       if ((ret&BLOCKED_DOWN) || !can_see(o,o->x,o->y,o->x,o->y+1))
  216.       {
  217.     o->set_state((character_state)S_landing);
  218.     the_game->play_sound(S_ALAND_SND,127,o->x,o->y);
  219.     o->set_aistate(ANT_LANDING);
  220.       }
  221.     } break;
  222.     case ANT_LANDING :
  223.     {
  224.       if (!o->next_picture())
  225.       {
  226.     long xv=0,yv=2;
  227.     o->try_move(o->x,o->y,xv,yv,1);
  228.     if (yv!=0)
  229.     {
  230.       o->set_gravity(1);
  231.       o->set_aistate(ANT_FALL_DOWN);
  232.     }
  233.     else
  234.     { 
  235.       o->set_state(stopped);
  236.       o->set_aistate(ANT_RUNNING);
  237.       return ant_ai;
  238.     }
  239.       }
  240.     } break;
  241.     case ANT_RUNNING :
  242.     {
  243.       if (player_list->next)
  244.       b=current_level->attacker(current_object);
  245.       else b=player_list->focus;
  246.       scream_check(o,b);
  247.       
  248.       
  249.       if ((jrand()%16)==0)  
  250.       o->lvars[ANT_need_to_dodge]=1;
  251.       if (!ant_dodge(o))
  252.       {
  253.     if ((o->x>b->x && o->direction==-1) || (o->x<b->x && o->direction==1))
  254.     {
  255.       o->next_picture();
  256.       if ((jrand()%4)==0 && abs(o->x-b->x)<180 && abs(o->y-b->y)<100 && can_hit_player(o,b))
  257.       {
  258.         o->set_state((character_state)S_weapon_fire);
  259.         o->set_aistate(ANT_FIRE);
  260.       } else if (abs(o->x-b->x)<100 && abs(o->y-b->y)<10 && (jrand()%4)==0)
  261.         o->set_aistate(ANT_POUNCE_WAIT);
  262.       else if (abs(o->x-b->x)>140 && !ant_congestion(o))
  263.         o->set_aistate(ANT_JUMP);
  264.       else 
  265.       {
  266.         long xm=o->direction>0 ? get_ability(o->otype,run_top_speed) : -get_ability(o->otype,run_top_speed);
  267.         long ym=0,new_xm=xm;
  268.         if (o->state!=running) o->set_state(running);
  269.  
  270.         o->try_move(o->x,o->y,new_xm,ym,3);
  271.         if (new_xm!=xm)    // blocked, see if we can climb ramp
  272.         {
  273.           new_xm=xm;
  274.           ym=-abs(xm);
  275.           o->try_move(o->x,o->y,new_xm,ym,3);
  276.           if (new_xm==xm)
  277.           {
  278.         o->x+=new_xm;
  279.         o->y+=ym;
  280.         new_xm=0;
  281.         ym=abs(xm);      // now get back on the ground
  282.         o->try_move(o->x,o->y,new_xm,ym,3);
  283.         o->x+=new_xm;
  284.         o->y+=ym;
  285.           } else
  286.           {
  287.         o->direction=0-o->direction;
  288.         o->set_aistate(ANT_JUMP);
  289.           }
  290.         } else
  291.           o->x+=new_xm;
  292.         new_xm=0;
  293.         ym=10;       // see if we should fall
  294.         o->try_move(o->x,o->y,new_xm,ym,3);
  295.         if (ym==10)
  296.           o->set_aistate(ANT_FALL_DOWN);
  297.         else o->y+=ym;
  298.       }
  299.     } else
  300.     {
  301.       o->direction=o->x>b->x ? -1 : 1;
  302.       o->set_aistate(ANT_LANDING);
  303.     }
  304.       }
  305.     } break;
  306.     
  307.     case ANT_POUNCE_WAIT :
  308.     {
  309.       if (!ant_dodge(o))
  310.       {
  311.     o->set_state((character_state)S_pounce_wait);
  312.     if (o->aistate_time()>alien_wait_time())
  313.     {
  314.       the_game->play_sound(S_ASLASH_SND,127,o->x,o->y);
  315.       o->set_state(stopped);
  316.       o->set_aistate(ANT_JUMP);
  317.     }
  318.       }
  319.     } break;
  320.  
  321.     case ANT_JUMP :
  322.     {
  323.       o->lvars[ANT_need_to_dodge]=0;
  324.       if (o->move(o->direction,-1,0)&BLOCKED_DOWN)
  325.       o->set_aistate(ANT_RUNNING);     
  326.     } break;
  327.     case ANT_FIRE :
  328.     {
  329.       if (!ant_dodge(o))
  330.       {
  331.     if (o->state==S_fire_wait)
  332.     {
  333.       if (!o->next_picture() || symbol_value(l_difficulty)==l_extreme)
  334.       {
  335.         if (player_list->next)
  336.         b=current_level->attacker(current_object);
  337.         else b=player_list->focus;
  338.         fire_at_player(o,b);
  339.         o->set_state(stopped);
  340.         o->set_aistate(ANT_RUNNING);
  341.       }
  342.     } else o->set_state((character_state)S_fire_wait);
  343.       }
  344.     } break;
  345.     case ANT_JUMP_ROOF :
  346.     {
  347.       o->lvars[ANT_need_to_dodge]=0;
  348.       o->set_state((character_state)S_jump_up);
  349. //      o->set_yvel(o->yvel()+1);
  350.       o->set_xacel(0);
  351.       long xv=0,yv=o->yvel();
  352.       o->y-=31;
  353.       o->try_move(o->x,o->y,xv,yv,1);
  354.       o->y+=31+yv;
  355.       if (yv!=o->yvel())
  356.       {
  357.     if (o->yvel()>0)
  358.     {
  359.       o->set_state(stopped);
  360.       o->set_aistate(ANT_RUNNING);
  361.     } else
  362.     {
  363.       o->set_state((character_state)S_top_walk);
  364.       o->set_aistate(ANT_ROOF_WALK);
  365.     }
  366.     o->set_yvel(0);
  367.       }
  368.     } break;
  369.     case ANT_ROOF_WALK :
  370.     {
  371.       if (player_list->next)
  372.       b=current_level->attacker(current_object);
  373.       else b=player_list->focus;
  374.       scream_check(o,b);     
  375.       if (((jrand()%8)==0 && abs(o->x-b->x)<10 && o->y<b->y) ||
  376.       o->lvars[ANT_need_to_dodge]==1)
  377.       {
  378.     o->set_gravity(1);
  379.     o->set_state(run_jump);
  380.     o->set_aistate(ANT_JUMP);
  381.     ant_ai();
  382.       }
  383.       else
  384.       {
  385.     if ((o->x>b->x && o->direction>0) || (o->x<b->x && o->direction<0))
  386.     o->direction=-o->direction;
  387.     else if (abs(o->x-b->x)<120 && (jrand()%4)==0)
  388.     {
  389.       o->set_state((character_state)S_ceil_fire);
  390.       o->set_aistate(ANT_CEIL_SHOOT);
  391.       ant_ai();
  392.     } else
  393.     {
  394.       int speed=o->direction>0 ? get_ability(o->otype,run_top_speed) : 
  395.                 -get_ability(o->otype,run_top_speed);
  396.       if (can_see(o,o->x,o->y-31,o->x+speed,o->y-31) &&
  397.           !can_see(o,o->x+speed,o->y-31,o->x+speed,o->y-32))
  398.       {
  399.         o->x+=speed;
  400.         if (!o->next_picture()) o->set_state((character_state)S_top_walk);
  401.         
  402.       } else o->set_aistate(ANT_FALL_DOWN);
  403.     }
  404.       }
  405.     } break;
  406.     case ANT_CEIL_SHOOT :
  407.     {
  408.       if (!o->next_picture())
  409.       {
  410.     if (player_list->next)
  411.       b=current_level->attacker(current_object);
  412.     else b=player_list->focus;
  413.     fire_at_player(o,b);
  414.     o->set_state((character_state)S_top_walk);
  415.     o->set_aistate(ANT_ROOF_WALK);
  416.       }
  417.     } break;
  418.   }
  419.   
  420.  
  421.   
  422.   return true_symbol;
  423. }
  424.  
  425.  
  426.  
  427. void fade_in(image *im, int steps);
  428. void fade_out(int steps);
  429.  
  430. void show_stats()
  431. {
  432.   if (current_level)
  433.   {
  434.     fade_out(8);
  435.     eh->set_mouse_position(0,0);
  436.     screen->clear();
  437.     image *im=cash.img(cash.reg("art/frame.spe","end_level_screen",SPEC_IMAGE,1));
  438.     im->put_image(screen,0,0);
  439.  
  440.  
  441.     int x1=im->width()+1,y1=0,x2=xres,y2=screen->height();
  442.     fade_in(NULL,16);
  443.  
  444.     char name[50];
  445.     strcpy(name,current_level->original_name());
  446.     char dig1=name[strlen(name)-strlen(".spe")-2];
  447.     char dig2=name[strlen(name)-strlen(".spe")-1];
  448.  
  449.    
  450.     char msg[50];
  451.  
  452.     if (isdigit(dig1) && isdigit(dig2))
  453.     {
  454.       if (dig1!='0')
  455.         sprintf(msg,"%s : %c%c",symbol_str("lev_complete"),dig1,dig2);
  456.       else
  457.         sprintf(msg,"%s : %c",symbol_str("lev_complete"),dig2);
  458.     } else sprintf(msg,"%s : %s",symbol_str("lev_complete"),current_level->original_name());
  459.  
  460.     int w=eh->font()->width()*strlen(msg),h=eh->font()->height();    
  461.     int x=(x1+x2)/2-w/2,y=(y1+y2)/2-h/2;
  462.     screen->bar(x-10,y-10,x+w+10,y+h+10,eh->bright_color());
  463.     screen->bar(x-9,y-9,x+w+9,y+h+9,eh->medium_color());
  464.  
  465.     eh->font()->put_string(screen,x+1,y+1,msg,eh->dark_color());    
  466.     eh->font()->put_string(screen,x,y,msg,eh->bright_color());
  467.     eh->flush_screen();
  468.     milli_wait(500);
  469.   }
  470.  
  471. }
  472.